package org.quickserver.net.client.loaddistribution.impl;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.quickserver.net.client.ClientInfo;
import org.quickserver.net.client.Host;
import org.quickserver.net.client.HostList;
import org.quickserver.net.client.loaddistribution.LoadPattern;
















public class RoundRobinLoadPattern
  implements LoadPattern
{
  private static final Logger logger = Logger.getLogger(RoundRobinLoadPattern.class.getName());
  
  private HostList hostList;
  
  private int pos;
  private final Object lock = new Object();

  
  public RoundRobinLoadPattern() { this.pos = -1; }


  
  public HostList getHostList() { return this.hostList; }

  
  public void setHostList(HostList hostList) { this.hostList = hostList; }

  
  public Host getHost(ClientInfo clientInfo) {
    List<Host> activeList = getHostList().getActiveList();
    
    if (activeList == null || activeList.isEmpty()) {
      logger.log(Level.WARNING, "No active list available to service requests {0}", activeList);
      return null;
    } 
    
    if (clientInfo != null) {
      if (clientInfo.getHostName() != null) {
        Host host = this.hostList.getHostByName(clientInfo.getHostName());
        if (host == null) {
          logger.log(Level.WARNING, "Host will name [{0}] not in hostlist!{1}", 
              new Object[] { clientInfo.getHostName(), this.hostList });
        }
        else if (host.getStatus() == 'A') {
          return host;
        } 
      } 

      
      if (clientInfo.getClientKey() != null) {
        int key = clientInfo.getClientKey().hashCode();
        int size = activeList.size();
        
        int mod = key % size;
        if (mod < 0) mod *= -1;
        
        return activeList.get(mod);
      } 
    } 
    
    int size = activeList.size();
    
    int mypos = 0;
    synchronized (this.lock) {
      this.pos++;
      if (this.pos >= size) {
        this.pos = 0;
      }
      mypos = this.pos;
    } 
    return activeList.get(mypos);
  }
}
